package com.petRescueCenter.demo.pet.entity.dto;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;

import com.petRescueCenter.demo.common.enumPackage.PetTypeEmun;
import com.petRescueCenter.demo.pet.entity.Pet;
import com.petRescueCenter.demo.user.entity.User;

import io.swagger.annotations.ApiModelProperty;

public class PetQueryDTO {
	@ApiModelProperty(name = "name", value = "宠物名字", required = false)
	private String name;
	@ApiModelProperty(name = "id", value = "宠物id", required = false)
	private Long id;
	@ApiModelProperty(name = "ownerName", value = "主人名字", required = false)
	private String ownerName;
	private String ownerId;
	@ApiModelProperty(name = "type", value = "宠物类型", required = false)
	private String type;
	private String noAdopted;

	public String getName() {
		return name;
	}

	public String getOwnerId() {
		return ownerId;
	}

	public void setOwnerId(String ownerId) {
		this.ownerId = ownerId;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getNoAdopted() {
		return noAdopted;
	}

	public void setNoAdopted(String noAdopted) {
		this.noAdopted = noAdopted;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getOwnerName() {
		return ownerName;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setOwnerName(String ownerName) {
		this.ownerName = ownerName;
	}

	public String getType() {
		return type;
	}

	@SuppressWarnings({ "serial" })
	public static Specification<Pet> getWhereClause(final PetQueryDTO petQueryDTO) {
		return new Specification<Pet>() {
			@Override
			public Predicate toPredicate(Root<Pet> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> predicate = new ArrayList<>();

				if (null != petQueryDTO.getId()) {
					predicate.add(criteriaBuilder.equal(root.get("id").as(Long.class), petQueryDTO.getId()));
				}
				if (StringUtils.isNotBlank(petQueryDTO.getType())) {
					if ("1".equals(petQueryDTO.getType())) {
						predicate.add(criteriaBuilder.equal(root.get("type").as(PetTypeEmun.class), PetTypeEmun.DOG));
					} else if ("0".equals(petQueryDTO.getType())) {
						predicate.add(criteriaBuilder.equal(root.get("type").as(PetTypeEmun.class), PetTypeEmun.CAT));
					} else {
						predicate.add(criteriaBuilder.equal(root.get("type").as(PetTypeEmun.class), PetTypeEmun.OTHER));
					}
				}
				if (null != petQueryDTO.getOwnerId()) {
					Join<Pet, User> join = root.join("owner", JoinType.LEFT);
					predicate.add(criteriaBuilder.equal(join.get("id").as(Long.class), petQueryDTO.getOwnerId()));
				}

				if (StringUtils.isNotBlank(petQueryDTO.getName())) {
					predicate.add(
							criteriaBuilder.like(root.get("name").as(String.class), "%" + petQueryDTO.getName() + "%"));
				}
				if (StringUtils.isNotBlank(petQueryDTO.getOwnerName())) {
					Join<Pet, User> join = root.join("owner", JoinType.LEFT);
					predicate.add(criteriaBuilder.like(join.get("name").as(String.class),
							"%" + petQueryDTO.getOwnerName() + "%"));
				}
				if (StringUtils.isNotBlank(petQueryDTO.getNoAdopted())) {
					predicate.add(criteriaBuilder.isNull(root.get("owner").as(User.class)));
				}

				Predicate[] pre = new Predicate[predicate.size()];
				return query.where(predicate.toArray(pre)).getRestriction();
			}
		};
	}
}
